1   /*
2    * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  /* ****************************************************************
27   ******************************************************************
28   ******************************************************************
29   *** COPYRIGHT (c) Eastman Kodak Company, 1997
30   *** As  an unpublished  work pursuant to Title 17 of the United
31   *** States Code.  All rights reserved.
32   ******************************************************************
33   ******************************************************************
34   ******************************************************************/
35  
36  package java.awt.image;
37  
38  import static sun.java2d.StateTrackable.State.*;
39  
40  /**
41   * This class extends <CODE>DataBuffer</CODE> and stores data internally as
42   * shorts.  Values stored in the short array(s) of this <CODE>DataBuffer</CODE>
43   * are treated as unsigned values.
44   * <p>
45   * <a name="optimizations">
46   * Note that some implementations may function more efficiently
47   * if they can maintain control over how the data for an image is
48   * stored.
49   * For example, optimizations such as caching an image in video
50   * memory require that the implementation track all modifications
51   * to that data.
52   * Other implementations may operate better if they can store the
53   * data in locations other than a Java array.
54   * To maintain optimum compatibility with various optimizations
55   * it is best to avoid constructors and methods which expose the
56   * underlying storage as a Java array as noted below in the
57   * documentation for those methods.
58   * </a>
59   */
60  public final class DataBufferUShort extends DataBuffer
61  {
62      /** The default data bank. */
63      short data[];
64  
65      /** All data banks */
66      short bankdata[][];
67  
68      /**
69       * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank and the
70       * specified size.
71       *
72       * @param size The size of the <CODE>DataBuffer</CODE>.
73       */
74      public DataBufferUShort(int size) {
75          super(STABLE, TYPE_USHORT, size);
76          data = new short[size];
77          bankdata = new short[1][];
78          bankdata[0] = data;
79      }
80  
81      /**
82       * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified number of
83       * banks, all of which are the specified size.
84       *
85       * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
86       * @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
87      */
88      public DataBufferUShort(int size, int numBanks) {
89          super(STABLE, TYPE_USHORT, size, numBanks);
90          bankdata = new short[numBanks][];
91          for (int i= 0; i < numBanks; i++) {
92              bankdata[i] = new short[size];
93          }
94          data = bankdata[0];
95      }
96  
97      /**
98       * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
99       * using the specified array.
100      * Only the first <CODE>size</CODE> elements should be used by accessors of
101      * this <CODE>DataBuffer</CODE>.  <CODE>dataArray</CODE> must be large enough to
102      * hold <CODE>size</CODE> elements.
103      * <p>
104      * Note that {@code DataBuffer} objects created by this constructor
105      * may be incompatible with <a href="#optimizations">performance
106      * optimizations</a> used by some implementations (such as caching
107      * an associated image in video memory).
108      *
109      * @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
110      * @param size The size of the <CODE>DataBuffer</CODE> bank.
111      */
112     public DataBufferUShort(short dataArray[], int size) {
113         super(UNTRACKABLE, TYPE_USHORT, size);
114         if (dataArray == null) {
115             throw new NullPointerException("dataArray is null");
116         }
117         data = dataArray;
118         bankdata = new short[1][];
119         bankdata[0] = data;
120     }
121 
122     /**
123      * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
124      * using the specified array, size, and offset.  <CODE>dataArray</CODE> must have at
125      * least <CODE>offset</CODE> + <CODE>size</CODE> elements.  Only elements
126      * <CODE>offset</CODE> through <CODE>offset</CODE> + <CODE>size</CODE> - 1 should
127      * be used by accessors of this <CODE>DataBuffer</CODE>.
128      * <p>
129      * Note that {@code DataBuffer} objects created by this constructor
130      * may be incompatible with <a href="#optimizations">performance
131      * optimizations</a> used by some implementations (such as caching
132      * an associated image in video memory).
133      *
134      * @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
135      * @param size The size of the <CODE>DataBuffer</CODE> bank.
136      * @param offset The offset into the <CODE>dataArray</CODE>.
137      */
138     public DataBufferUShort(short dataArray[], int size, int offset) {
139         super(UNTRACKABLE, TYPE_USHORT, size, 1, offset);
140         if (dataArray == null) {
141             throw new NullPointerException("dataArray is null");
142         }
143         if ((size+offset) > dataArray.length) {
144             throw new IllegalArgumentException("Length of dataArray is less "+
145                                                " than size+offset.");
146         }
147         data = dataArray;
148         bankdata = new short[1][];
149         bankdata[0] = data;
150     }
151 
152     /**
153      * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified arrays.
154      * The number of banks will be equal to <CODE>dataArray.length</CODE>.
155      * Only the first <CODE>size</CODE> elements of each array should be used by
156      * accessors of this <CODE>DataBuffer</CODE>.
157      * <p>
158      * Note that {@code DataBuffer} objects created by this constructor
159      * may be incompatible with <a href="#optimizations">performance
160      * optimizations</a> used by some implementations (such as caching
161      * an associated image in video memory).
162      *
163      * @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
164      * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
165      */
166     public DataBufferUShort(short dataArray[][], int size) {
167         super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length);
168         if (dataArray == null) {
169             throw new NullPointerException("dataArray is null");
170         }
171         for (int i=0; i < dataArray.length; i++) {
172             if (dataArray[i] == null) {
173                 throw new NullPointerException("dataArray["+i+"] is null");
174             }
175         }
176 
177         bankdata = (short[][]) dataArray.clone();
178         data = bankdata[0];
179     }
180 
181     /**
182      * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with specified arrays,
183      * size, and offsets.
184      * The number of banks is equal to <CODE>dataArray.length</CODE>.  Each array must
185      * be at least as large as <CODE>size</CODE> + the corresponding offset.   There must
186      * be an entry in the offset array for each <CODE>dataArray</CODE> entry.  For each
187      * bank, only elements <CODE>offset</CODE> through
188      * <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
189      * used by accessors of this <CODE>DataBuffer</CODE>.
190      * <p>
191      * Note that {@code DataBuffer} objects created by this constructor
192      * may be incompatible with <a href="#optimizations">performance
193      * optimizations</a> used by some implementations (such as caching
194      * an associated image in video memory).
195      *
196      * @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
197      * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
198      * @param offsets The offsets into each array.
199      */
200     public DataBufferUShort(short dataArray[][], int size, int offsets[]) {
201         super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length, offsets);
202         if (dataArray == null) {
203             throw new NullPointerException("dataArray is null");
204         }
205         for (int i=0; i < dataArray.length; i++) {
206             if (dataArray[i] == null) {
207                 throw new NullPointerException("dataArray["+i+"] is null");
208             }
209             if ((size+offsets[i]) > dataArray[i].length) {
210                 throw new IllegalArgumentException("Length of dataArray["+i+
211                                                    "] is less than size+"+
212                                                    "offsets["+i+"].");
213             }
214 
215         }
216         bankdata = (short[][]) dataArray.clone();
217         data = bankdata[0];
218     }
219 
220     /**
221      * Returns the default (first) unsigned-short data array.
222      * <p>
223      * Note that calling this method may cause this {@code DataBuffer}
224      * object to be incompatible with <a href="#optimizations">performance
225      * optimizations</a> used by some implementations (such as caching
226      * an associated image in video memory).
227      *
228      * @return The first unsigned-short data array.
229      */
230     public short[] getData() {
231         theTrackable.setUntrackable();
232         return data;
233     }
234 
235     /**
236      * Returns the data array for the specified bank.
237      * <p>
238      * Note that calling this method may cause this {@code DataBuffer}
239      * object to be incompatible with <a href="#optimizations">performance
240      * optimizations</a> used by some implementations (such as caching
241      * an associated image in video memory).
242      *
243      * @param bank The bank whose data array you want to get.
244      * @return The data array for the specified bank.
245      */
246     public short[] getData(int bank) {
247         theTrackable.setUntrackable();
248         return bankdata[bank];
249     }
250 
251     /**
252      * Returns the data arrays for all banks.
253      * <p>
254      * Note that calling this method may cause this {@code DataBuffer}
255      * object to be incompatible with <a href="#optimizations">performance
256      * optimizations</a> used by some implementations (such as caching
257      * an associated image in video memory).
258      *
259      * @return All of the data arrays.
260      */
261     public short[][] getBankData() {
262         theTrackable.setUntrackable();
263         return (short[][]) bankdata.clone();
264     }
265 
266     /**
267      * Returns the requested data array element from the first (default) bank.
268      *
269      * @param i The data array element you want to get.
270      * @return The requested data array element as an integer.
271      * @see #setElem(int, int)
272      * @see #setElem(int, int, int)
273      */
274     public int getElem(int i) {
275         return (int)(data[i+offset]&0xffff);
276     }
277 
278     /**
279      * Returns the requested data array element from the specified bank.
280      *
281      * @param bank The bank from which you want to get a data array element.
282      * @param i The data array element you want to get.
283      * @return The requested data array element as an integer.
284      * @see #setElem(int, int)
285      * @see #setElem(int, int, int)
286      */
287     public int getElem(int bank, int i) {
288         return (int)(bankdata[bank][i+offsets[bank]]&0xffff);
289     }
290 
291     /**
292      * Sets the requested data array element in the first (default) bank
293      * to the specified value.
294      *
295      * @param i The data array element you want to set.
296      * @param val The integer value to which you want to set the data array element.
297      * @see #getElem(int)
298      * @see #getElem(int, int)
299      */
300     public void setElem(int i, int val) {
301         data[i+offset] = (short)(val&0xffff);
302         theTrackable.markDirty();
303     }
304 
305     /**
306      * Sets the requested data array element in the specified bank
307      * from the given integer.
308      * @param bank The bank in which you want to set the data array element.
309      * @param i The data array element you want to set.
310      * @param val The integer value to which you want to set the specified data array element.
311      * @see #getElem(int)
312      * @see #getElem(int, int)
313      */
314     public void setElem(int bank, int i, int val) {
315         bankdata[bank][i+offsets[bank]] = (short)(val&0xffff);
316         theTrackable.markDirty();
317     }
318 }